package ua.kpi_java_training.zabrodskyi.module1;

import java.util.Scanner;

/**
 * Class is designed to get a phrase (string) from the console and output
 * substring-palindromes to the console.
 * 
 * @version 1.10 25 May 2013
 * @author Maksym Zabrodskyi
 */
public class PalindromeFinder {

	/**
	 * Value minimum length of a palindrome, by default is
	 * {@value #MIN_PALINDROME_LENGTH} characters.
	 */
	private static final int MIN_PALINDROME_LENGTH = 3;

	/**
	 * In this method other methods by means of which get a word or a phrase
	 * from the console, there is a search of all substrings-palindromes and
	 * their output to the console.
	 * 
	 * @param args
	 *            - not used.
	 */
	public static void main(String[] args) {
		String phrase = getPhraseFromConsole();
		String palindromes = findPalindromes(phrase);
		outputToConsole(palindromes);
	}

	/**
	 * Do a search of all substrings-palindromes in the input phrase.
	 * 
	 * @param phrase
	 *            - source-phrase.
	 * @return a list (data type - string) of all found substring-palindromes.
	 */
	public static String findPalindromes(String phrase) {
		String listPalindromes = "";
		int size = phrase.length();
		for (int beginIndex = 0; beginIndex <= size - MIN_PALINDROME_LENGTH; beginIndex++) {
			for (int endIndex = beginIndex + MIN_PALINDROME_LENGTH; endIndex <= size; endIndex++) {
				String subPhrase = phrase.substring(beginIndex, endIndex);
				listPalindromes = addOnlyPalindrome(listPalindromes, subPhrase);
			}
		}
		return listPalindromes;
	}

	/**
	 * Adds to the list of palindromes only the substring which is a palindrome.
	 * 
	 * @param listPalindromes
	 *            - a list of palindromes.
	 * @param subPhrase
	 *            - a part of the source phrase, which is checked is it a
	 *            palindrome.
	 * @return a list of palindromes to which it was added new substring
	 *         palindrome.
	 */
	public static String addOnlyPalindrome(String listPalindromes,
			String subPhrase) {
		if (isPalindrome(subPhrase)) {
			listPalindromes += subPhrase + "\n";
		}
		return listPalindromes;
	}

	/**
	 * Check: a word is a palindrome.
	 * 
	 * @param word
	 *            - a word which is checked.
	 * @return true if the given word is a palindrome, false otherwise.
	 */
	public static boolean isPalindrome(String word) {
		return word.equals(new StringBuffer(word).reverse().toString());
	}

	/**
	 * Gets a phrase from the console. Length of the input phrase should be
	 * equal to or more than minimum length of the word, which is a palindrome.
	 * 
	 * @return string phrase-source to search for palindromes.
	 * @see {@link #MIN_PALINDROME_LENGTH Minimum length of a palindrome.}
	 */
	public static String getPhraseFromConsole() {
		System.out.println("Program of search of palindromes.");
		Scanner scanner = new Scanner(System.in);
		String inputPhrase = "";
		while (!isPhraseCorrect(inputPhrase)) {
			System.out.print("Enter please the phrase ");
			System.out.printf("(more than %d characters):\n",
					MIN_PALINDROME_LENGTH);
			inputPhrase = scanner.nextLine();
		}
		scanner.close();
		return inputPhrase;
	}

	/**
	 * Do verification - is the input phrase is correctly.
	 * 
	 * @param inputPhrase
	 *            - a text phrase.
	 * @return true if the input phrase length equal to or more than
	 *         {@link #MIN_PALINDROME_LENGTH minimum length of a palindrome},
	 *         false otherwise.
	 * @see {@link #MIN_PALINDROME_LENGTH Minimum length of a palindrome.}
	 */
	public static boolean isPhraseCorrect(String inputPhrase) {
		return inputPhrase.length() >= MIN_PALINDROME_LENGTH;
	}

	/**
	 * Output list of substring-palindromes to the console. If a
	 * substring-palindromes are not found, a message is displayed.
	 * 
	 * @param list
	 *            - a list (data type - string) of all found
	 *            substring-palindromes.
	 */
	public static void outputToConsole(String list) {
		if (list.length() == 0) {
			System.out.println("Palindromes are not found.");
		} else {
			System.out.println("The found palindromes:");
			System.out.println(list);
		}
	}

}
